#!/usr/bin/env python
# -*- coding: utf-8 -*-

#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#
#  WPA Interface Module
#
#  Developed by Joao Rodrigues - gothicknight@gmail.com
#
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#
#    This file is part of wifiTools.
#
#    wifiTools is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    any later version.
#
#    wifiTools is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with wifiTools; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

# Bibliotecas de sistema
import os
import time
import sys
from subprocess import Popen, PIPE

# User information
uid		= os.getuid()

# WPA system paths
wpaconFILE	="/etc/wpa_supplicant-pyeU.conf"
wpaconDEMO	="wpaconf.demo"
wpaRunFile	="/var/run/wpa_supplicant"

#-------------------------------------------------------------------------------------------------
def version():
	"""Versao da Libraria"""

	return "v.20061017"
#-------------------------------------------------------------------------------------------------
#ON DEVELOPMENT
#		- Preciso testar se a autenticacao foi bem sucedida (user/pass correcta)(servidor ok)		#(TEST)#
def WpaConnect(dev,wait=30,sec=2.0):
	"""Liga a uma rede com WEP/WPA usando o wpa_supplicant"""

	elem	= ""
	wcount	= 0
	temp	= ""
	nESTADO = 2
	ESTADO	= ""

	if uid != 0:
		print >>sys.stderr.write(" E Nao tens permissoes para ligar a redes")
		return -1

	print " * Ligando o dispositivo %s ..." % str(dev)
	os.system("ifconfig "+str(dev)+" allmulti up")
	print " * Autenticando usando "+wpaconFILE

	os.popen("wpa_supplicant -Dwext -i "+str(dev)+" -B -c "+wpaconFILE+" &")

	while wcount<=wait:

		wcount += 1
		time.sleep(sec)
		p	= Popen("wpa_cli status | grep wpa_state", shell=True, stdout=PIPE)
		out	= p.stdout.read().split("=")

		try:
			ESTADO	= out[1].split("\n")[0]
		except:
			print >>sys.stderr.write("\t E Nao e possivel obter dados do estado da autenticacao")
			return False
		
		if "ASSOCIATING" in ESTADO and nESTADO != 0 :
			print "\t > A associar ao servidor de autenticacao"
			nESTADO = 0
		if "ASSOCIATED" in ESTADO and nESTADO != 1 :
			print "\t > A efectuar a autenticacao"
			nESTADO = 1
		if "COMPLETED" in ESTADO:
			print "\t > Autenticado"
			wcount=999
		p.stdout.close()
	if ( wcount >= wait ) and  (wcount != 999 ) :
		print >>sys.stderr.write(" E Falhou a autenticacao (timeout)")
		WpaKill()
		return False
	if wcount == 999:
		return True
#-------------------------------------------------------------------------------------------------
#TESTING - #(Preciso fazer testes)#
def getWpaStatus():
	"""Retorna o estado do cliente de autenticacao WPA"""

	keymgmt		= ""
	wpastate	= ""

	if os.access(wpaRunFile, os.F_OK):
		p = Popen("wpa_cli status",shell=True, stdout=PIPE)
		out = p.stdout.read().splitlines()
		p.stdout.close()
		for elem in out:
#			if "ssid" in elem:
#				DevState["ssid"]=elem.split("=")[1]
			if "key_mgmt" in elem:
				keymgmt=elem.split("=")[1]
			if "wpa_state" in elem:
				wpastate=elem.split("=")[1]
		return [True,keymgmt,wpastate]
	else:
		return [False,"",""]
#-------------------------------------------------------------------------------------------------
#TESTING - #(Preciso fazer testes)#
def setWpaConf(username,password):
	"""Funcao para criar um ficheiro de autenticacao para a e-U"""

	config = []
	
	if uid != 0:
		print >>sys.stderr.write(" E Nao tens permissoes")
		return False
	
	if not ( os.access(wpaconDEMO,os.R_OK | os.F_OK) ):
		print " E Nao consegui ler "+wpaconDEMO
		return False

	file_io = open(wpaconDEMO,"r")
	for elem in file_io:
		if str(elem).startswith("\tidentity"):
			config.append("\tidentity=\""+str(username)+"\"\n")
		else:
			if str(elem).startswith("\tpassword"):
				config.append("\tpassword=\""+str(password)+"\"\n")
			else:
				config.append(str(elem))
	file_io.close()

	if not ( os.access(wpaconFILE, os.F_OK) ):
		os.system("touch "+wpaconFILE)

	if not ( os.access(wpaconFILE, os.W_OK) ):
		print >>sys.stderr.write(" E Nao consegui escrever em "+wpaconFILE)
		return False

	file_io = open(wpaconFILE,"w")
	file_io.writelines(config)
	file_io.close()
	print " * Definido novo "+wpaconFILE
	return True

#-------------------------------------------------------------------------------------------------
#ON DEVELOPMENT - Pode killar outros wpa_supplicants
def WpaKill():
	"""Faz um killall wpa_supplicant"""

	print " * Verificando o estado do wpa_supplicant"
	if getWpaStatus()[0]:
		print "\t> Desligando wpa_supplicant"
		os.system("killall wpa_supplicant 2> /dev/null &")
	else:
		print "\tW wpa_kill() - Nao existem processos a correr"
#-------------------------------------------------------------------------------------------------
def getWpaConf():
	"""Funcao para ler a configuracao de autenticacao para a e-U"""

	tmp 		= []
	config 		= []
	
	if not ( os.access(wpaconFILE, os.F_OK|os.R_OK) ):
		print >>sys.stderr.write(" E Nao consegui ler "+wpaconFILE)
		return False

	file_io = open(wpaconFILE,"r")
	for elem in file_io:
		if "identity" in str(elem):
			tmp = str(elem).split("=")
			tmp = tmp[1].split("\n")
			tmp = tmp[0].split("\"")
			config.append(tmp[1])
		if "password" in str(elem):
			tmp = str(elem).split("=")
			tmp = tmp[1].split("\n")
			tmp = tmp[0].split("\"")
			config.append(tmp[1])
	file_io.close()
	return config
#EOF
